--[[
Name: unitDoodles.config
Author: Sonora (The Dragonflight, US Kirin Tor)
Website & SVN: http://code.google.com/p/browniehelper/source/browse/#svn/trunk/unitDoodles.config
License: GNU General Public License v3
]]

local AceConfig = LibStub("AceConfig-3.0")
local AceConfigDialog = LibStub("AceConfigDialog-3.0")
local AceGUI = LibStub("AceGUI-3.0")

--Utilities
local function keys(t)
    ks = {}
    for k,_ in pairs(t) do table.insert(ks, k) end
    return ks
end

--Dialogs
local function inputBox(msg, default, callback)

    StaticPopupDialogs["unitDoodles_INPUTBOX"] = {
        text = msg,
        button1 = "Add",
        button2 = "Cancel",
    
        OnShow = function (self, data)
            self.editBox:SetText(default)
        end,
        OnAccept = function (self, data, data2)
            local text = self.editBox:GetText()
            callback(text)
        end,
        hasEditBox = true,
        timeout = 0,
        whileDead = true,
        hideOnEscape = true,
    }
    
    StaticPopup_Show ("unitDoodles_INPUTBOX")
    
end

local function yesnoBox(msg, callback)
    StaticPopupDialogs["unitDoodles_YESNOBOX"] = {
        text = msg,
        button1 = "Yes",
        button2 = "No",
        OnAccept = function(self, data, data2)
            callback()
        end,
        timeout = 0,
        whileDead = true,
        hideOnEscape = true,
    }
    
    StaticPopup_Show ("unitDoodles_YESNOBOX")
end

local function msgBox(msg)
    StaticPopupDialogs["unitDoodles_MSGBOX"] = {
        text = msg,
        button1 = "Ok",
        button2 = nil,
        timeout = 0,
        whileDead = true,
        hideOnEscape = true,
    }
    
    StaticPopup_Show ("unitDoodles_MSGBOX")
end

--Panel & dialog creators
function unitDoodlesConfig:createBasePanel()

    local function getDoodleSets()
        local doodleSets = {}
    
        for _, setName in ipairs(self:getDoodleSetNames()) do
            doodleSets[setName] = {
                type = 'toggle',
                name = setName,
                get = function() return self:doodleSetIsLoaded(setName) end,
                set = function(info, value) 
                    if value == true then
                        table.insert(self.config.loadDoodleSets, setName)
                    else
                        for i,v in ipairs(self.config.loadDoodleSets) do
                            if v == setName then
                                table.remove(self.config.loadDoodleSets, i)
                            end
                        end
                    end
                    self:updateConfig()
                end,
            }
        end
        
        return doodleSets
        
    end

    return {
        type = "group",
        name = "UnitDoodles Configuration",
        args={
            introduction = {
                type = 'description',
                name = "UnitDoodles allows you to attach |cffFF7D0Adoodles|r (time bars, indicator dots, etc.) to unit frames.  Use this panel to select which sets of doodles should be loaded with this |cffFF7D0AProfile|r.  Use the |cffFF7D0ADoodles|r panel to configure the doodle sets shown here.  Use the |cffFF7D0AUnit frames|r panel to configure unitDoodles to work with your unit frame addon.\n\nHappy doodling!",
                order = 1
            },
            doodleSets = {
                type = 'group',
                name = 'Loaded doodle sets',
                desc = 'Check or uncheck doodle sets to configure which doodles are currently shown.',
                guiInline = true,
                args = getDoodleSets(),
                order = 10,
            },
            h1 = {
                type = 'header',
                name = 'Performance',
                order = 20,
            },
            t1 = {
                type = 'description',
                name = 'It is strongly recommended that you reload your user interface after making any adjustments to doodles.  This will help to free up memory and make the game more responsive.',
                order = 21,
            },
            reloadUI = {
                type = 'execute',
                name = 'Reload',
                desc = 'Reloads the WoW user interface.',
                func = function() ReloadUI() end,
                order = 22,
            },
            roundRobin = {
                type = 'toggle',
                name = 'Round robin updates',
                desc = 'If checked each doodle is updated one-at-a-time; if unchecked all doodles are updated simultaneously.  Unchecking this option may improve the smoothness of animations but will dramatically increase processing overhead if you are using a lot of doodles.',
                get = function() return unitDoodles.reactor.roundRobin end,
                set = function(into, value) unitDoodles.reactor.roundRobin = value end,
                order = 23,
            },

        },
    }
    
end

function unitDoodlesConfig:createUnitFramesPanel(reloadPanel)

    local function printMousePosition()
        f = EnumerateFrames()
        while f do
            if f:IsVisible() and MouseIsOver(f) and f:GetName()~= nil then print(f:GetName()) end
            f = EnumerateFrames(f)
        end
    end
    self:RegisterChatCommand('mouse', printMousePosition)

    local function makeFrameInput(variableName)
        return {
            type = 'input',
            name = variableName,
            desc = "Name of the frame to which '"..variableName.."' doodles will be attached.",
            get = function()
                return self.config.frameSets[self.config.currentFrameSet][variableName] 
            end,
            set = function(info,value) 
                self.config.frameSets[self.config.currentFrameSet][variableName] = value 
                self:updateConfig()
                reloadPanel()
            end,
        }
    end

    local function makeUnitFrameInputs()
    
        local args = {}
        for i, unitName in ipairs(self:getUnitNames(false)) do
            args[unitName] = makeFrameInput(unitName)
            args[unitName].order = 10 + i
        end
    
        args['addNewUnitName'] = {
            type = 'execute',
            name = 'Add new entry',
            desc = 'You can drop doodles on pretty much any UI element, not just unit frames.  Add names of doodle targets here and provide valid Frame names to make new doodle targets available when editing doodle sets.',
            func = function()
                inputBox("Enter the name of a new type of unit/frame element to attach doodles to.  To keep with convention, please use all lowercase.", "doodletarget",
                    --Callback
                    function(text)
                        self.config.frameSets[self.config.currentFrameSet][text] = text
                        self:updateConfig()
                        reloadPanel()
                    end
                )
            end,
            order = 100
        }
    
        return args
    end

    return {
        type = 'group',
        name = "Unit Frames",
        args = {
            desc = {
                type = 'description',
                name = 'Use this panel to configure unit doodles to work with your unit frames addon, or choose "default" below if you use the standard WoW user-interface.  Unit frames addons use different frames names.  If unitDoodles is not already setup to work with your unit frames, you can create a new entry and associate units with the correct frame names below.\n\nFor party and raid frames you can use the variable |cffFF7D0A$p|r to represent the party member number, |cffFF7D0A$g|r to represent the raid group number, and |cffFF7D0A$r|r to represent the raid member number.\n\nTo find out what your addon has named its frames, mouse over a frame and use the |cffFF7D0A/mouse|r chat command to get a list of frame names under your cursor.',
                order = 0,
            },
            currentUnitFrameSet = {
                type = 'select',
                name = 'Current unit frames',
                desc = 'Name of the unit frames addon that you are using (or "default" for built-in unit frames)',
                values = function() 
                    local values = {}
                    for name,_ in pairs(self.config.frameSets) do values[name]=name end
                    return values
                end,
                get = function()
                    return self.config.currentFrameSet
                end,
                set = function(info, value)
                    self.config.currentFrameSet = value
                    self:updateConfig()
                end,
                width = "normal",
                order = 1
            },
            new = {
                type = 'execute',
                name = 'New',
                desc = 'Create a new unit frames entry',
                func = function()
                    inputBox("Enter a name for the new unit frame set:", "", 
                        function(text) 
                            self.config.frameSets[text] = {}
                            self.config.currentFrameSet = text
                            self:updateConfig()
                            reloadPanel()
                    end)
                end,
                order = 3
            },
        
            frameNames = {
                type = 'group',
                guiInline = true,
                name = 'Frame names',
                args = makeUnitFrameInputs()
            },
            playerInGroupFrames = {
                type = 'toggle',
                name = 'Player shown in group',
                desc = 'Some unit frame addons show the player in the party frames, others (like the default) do not.  If yours does, check this box.',
                get = function() return self.config.frameSets[self.config.currentFrameSet].playerInGroupFrames end,
                set = function(info, value) self.config.frameSets[self.config.currentFrameSet].playerInGroupFrames=value end,
            },
        }
    }
    
end

function unitDoodlesConfig:createDoodleDefaultsPanel(reloadPanel)

    local updateConfig = function() self:updateConfig() end

    local defaultsPanel = {
        type = "group",
        name = "Doodle Defaults",
        args={
            introduction = {
                type = 'description',
                name = "Doodles inherit default visual and positioning properties based on their type.  You can edit default values for different types of doodles on this page and the changes will be propagated to all doodles that don't define these properties explicitly.",
                order = 1
            },
            sep = {
                type = 'header',
                name = 'Defaults',
                order = 2,
            },
        }
    }
    
    --Create an entry for each default table
    for defaultName, defaultTable in pairs(self.config.doodleDefaults) do
        local newDefaultGroup = {
            type = 'group',
            name = defaultName,
            args = {},
        }
    
        --Inject options table handlers for each property defined in this default table
        for propertyName, value in pairs(defaultTable) do
            newDefaultGroup.args[propertyName] = self:getPropertyHandler(defaultTable, propertyName, updateConfig, reloadPanel)
        end
    
        defaultsPanel.args[defaultName] = newDefaultGroup
    end
    
    return defaultsPanel
end

function unitDoodlesConfig:createDoodleSetsPanel(reloadPanel)

    local function getDoodleSets()
        
        args = {}
        args.header = {
            type = 'execute',
            name = 'Add new set',
            func = function()
                inputBox('Enter a name for the new doodle set (entering an existing name will overwrite the current set):', 'newDoodleSet',
                    function(text)
                        local function addSet()
                            self.config.doodleSets[text] = {}
                            self:updateConfig()
                            reloadPanel()
                        end

                        if self.config.doodleSets[text] == nil then addSet()
                        else
                            yesnoBox("You already have a doodle set named '"..text.."'.  Adding a new set with this name will delete the old set.  Are you sure you want to do this?", addSet)
                        end
                    end
                )
            end,
            order = 1,
        }
        for setName, setTable in pairs(self.config.doodleSets) do
    
            args[setName] = {
                type = 'group',
                name = setName,
                args = {
                    description = {
                        type = 'description',
                        name = '|cffFF7D0ADoodled units:|r '..(#keys(setTable)>0 and table.concat(keys(setTable), ", ") or "none"),
                        order = 1,                                   
                    },
                    edit = {
                        type = 'execute',
                        name = 'Edit doodles',
                        desc = 'Opens a new window that will allow you to edit the doodles in this set.',
                        func = function()
                            self:editDoodleSet(setName)
                            InterfaceOptionsFrame:Hide()
                        end,
                        order = 2,
                    },
                    share = {
                        type = 'execute',
                        name = 'Share',
                        desc = 'Allows you to share this doodle set with another character in-game or through text copied to the clipboard.',
                        func = function() 
                            self:shareDoodleSet(setName)
                            InterfaceOptionsFrame:Hide()
                        end,
                        order = 3,
                    },
                    delete = {
                        type = 'execute',
                        name = 'Delete set',
                        desc = 'Deletes this doodle set.  Be careful!',
                        func = function()
                            yesnoBox('Are you sure you want to delete this doodle set? ('..setName..')', function()
                                self.config.doodleSets[setName] = nil
                                self:updateConfig()
                                reloadPanel()
                            end)
                        end,
                        order = 5,
                    },
                }
            }
            
        end
        return args
    end

    return {
        type = "group",
        name = "Doodles",
        args={
            introduction = {
                type = 'description',
                name = "The tools on this page will allow you to customize your existing doodles, change their appearance, or create new sets of doodles.",
                order = 1
            },
            helpMsg = {
                type = 'execute',
                name = 'About doodles',
                func = function()
                    msgBox("|cffFF7D0AConcerning Doodles...|r\nFour things to understand about doodles before getting started:\n\n|cffFF7D0ADoodle sets.|r  Doodles are organized into sets.  This allows you to easily turn off or on related groupings of doodles using the main configuration page.\n\n|cffFF7D0ADoodle defaults.|r  Doodles inherit basic functionality and appearance properties based on their type.  This allows you to just specify the properties you need to tweak on a doodle-by-doodle basis.  To edit the default properties for different types of doodles, hit 'Edit doodle defaults' below.\n\n|cffFF7D0AUnits|r.  Doodles are usually associated with specific units (like the player, or your target), which means they report on some aspect of that unit's state and are positioned on screen using the corresponding unit frame.  Some 'unit' names used in unitDoodles aren't real unitID's but indicate that a set of doodles should be applied to a set of units.  For example, using the unit name 'party' will apply doodles to each party member or 'group' will apply doodles to all party and raid members.\n\n|cffFF7D0APositioning|r.  Doodles can be positioned by three different methods.  The simplest is to define a 'Fixed point' on the 'parent' unit frame to anchor the doodle to.  The second option is to 'Advance' a doodle's position based on a previous doodles in a set.  The third is to 'Stack' doodles so that their positions update based on doodles currently being shown in the set. Note the first doodle for a unit within a set must define a 'Fixed point' or doodles will show up in odd places.")
                end,
                desc = "Opens a dialog containing some background information about how doodles work.",
                order = 5,
            },
            editDefaults = {
                type = 'execute',
                name = 'Edit doodle defaults',
                func = function()
                    self:editDoodleDefaults()
                    InterfaceOptionsFrame:Hide()
                end,
                desc = "Opens a new dialog box that will allow you to edit the default doodle settings.",
                order = 4,
            },
            h1 = {
                type = 'header',
                name = 'Doodle sets',
                order = 10,
            },
            doodleSets = {
                type = 'group',
                name = 'Doodle Sets',
                order = 20,
                args = getDoodleSets(),
            }
            
        }
    }
end



function unitDoodlesConfig:createDoodlePanel(setName, reloadPanel)

    local doodleSet = self.config.doodleSets[setName]
    local updateConfig = function() self:updateConfig() end

    --Figure out the names of unused unit types
    local unitTypes = unitDoodlesConfig:getUnitNames(includeMacros)
    local unusedTypes = {}
    for _, unitName in ipairs(unitTypes) do
        if doodleSet[unitName] == nil then
            unusedTypes[unitName] = unitName
        end
    end
    local unitTypeToAdd = keys(unusedTypes)[1]

    local options = {
        type = 'group',
        name = setName,
        args = {
            selectNewUnit = {
                type = 'select',
                name = 'Available units',
                desc = 'Select an unused unit or unit group name to add a new entry to this doodle set.',
                values = unusedTypes,
                disabled = unitTypeToAdd == nil,
                get = function() return unitTypeToAdd end,
                set = function(info, value) unitTypeToAdd=value end,
                order = 100,
            },
            addUnit = {
                type = 'execute',
                name = 'Add unit',
                desc = 'Add a new entry to this doodle set for the selected unit or unit group.',
                disabled = unitTypeToAdd == nil,
                func = function()
                    doodleSet[unitTypeToAdd] = {}
                    self:updateConfig()
                    reloadPanel()
                end,
                order = 101,
            },
        }
    }
    
    --Make doodle property groups for each unit, in order (properties get inlined within each doodle)
    local function addInheritedTable(builtDoodleTable, inheritedTables)
        if builtDoodleTable.inherits ~= nil then
            table.insert(inheritedTables, builtDoodleTable.inherits)
            if builtDoodleTable.inherits.inherits ~= nil then
                addInheritedTable(builtDoodleTable.inherits, inheritedTables)
            end
        end
    end
    
    local doodleTypeNames = {}
    for doodleCategory, doodleTypes in pairs(unitDoodles.doodles) do
        for doodleType,_ in pairs(doodleTypes) do
            if doodleCategory ~= 'abstract' then
                local doodleTypeName = 'doodles.'..doodleCategory..'.'..doodleType
                doodleTypeNames[doodleTypeName] = doodleTypeName
            end
        end
    end
    local doodleTypeToAdd = keys(doodleTypeNames)[1]
    
    for unitName, doodles in pairs(doodleSet) do
    
        options.args[unitName] = {
            type = 'group',
            name = unitName,
            args = {
                doodleTypes = {
                    type = 'select',
                    name = 'Doodle type to add',
                    order = 100,
                    values = doodleTypeNames,
                    get = function() return doodleTypeToAdd end,
                    set = function(info, value) doodleTypeToAdd=value end,
                    disabled = doodleTypeToAdd == nil,
                },
                addNew = {
                    type = 'execute',
                    name = 'Add doodle',
                    func = function()
                        table.insert(self.config.doodleSets[setName][unitName], {doodleType=doodleTypeToAdd})
                        self:updateConfig()
                        reloadPanel()
                    end,
                    disabled = doodleTypeToAdd == nil,
                    order = 101,
                }
            },
            order = 10
        }
        
        --Inject doodle groups for each doodle on this unit
        for i, doodle in ipairs(doodles) do
    
            --Discover this doodle's inheritance structure
            local inheritedTables = {}
            addInheritedTable(unitDoodles.config.doodleSets[setName][unitName][i], inheritedTables)
        
            --Find all properties defined on default tables associated with doodles in the inheritance tree
            local inheritedProperties = {}
            for doodleReference, defaultTable in pairs(self.config.doodleDefaults) do
                local defaultTarget = unitDoodles.eval(doodleReference)
                for _, inheritedTable in ipairs(inheritedTables) do
                    if defaultTarget == inheritedTable then
                        for k,v in pairs(defaultTable) do 
                            if doodle[k] == nil and inheritedProperties[k]==nil then inheritedProperties[k]=v end
                        end
                        break
                    end
                end
            end
            
            --Keep track of which inherited properties we can override, and what is set in the drop down
            local availableProperties = {}
            for k,_ in pairs(inheritedProperties) do
                if self:hasHandler(k) then
                    availableProperties[k] = k
                end
            end
            local propertyToAdd = keys(inheritedProperties)[1]
        
            --Create an options table for this doodle
            options.args[unitName].args["doodle"..i] = {
                type = 'group',
                name = (unitDoodles.config.doodleSets[setName][unitName][i].getDescription and unitDoodles.config.doodleSets[setName][unitName][i]:getDescription() or 'Doodle '..i),
                guiInline = true,
                args = {
                    --Add a section to summarize inherited properties
                    h1 = {
                        type = 'header',
                        name = 'Inherited properties',
                        order = 100
                    },
                    propertyList = {
                        type = 'description',
                        name =  table.concat(keys(inheritedProperties), ", "),
                        order = 101,
                    },
                    overrideProperty = {
                        type = 'select',
                        name = 'Property to override',
                        order = 102,
                        desc = 'Select a property to override.  Please note that some properties may not be supported by the in-game configuration interface.',
                        values = availableProperties,
                        disabled = propertyToAdd == nil,
                        get = function() return propertyToAdd end,
                        set = function(info, value) propertyToAdd = value end,
                    },
                    addProperty = {
                        type = 'execute',
                        name = 'Override',
                        order = 103,
                        desc = 'Override an inherited property with a setting that is specific to this doodle.',
                        disabled = propertyToAdd == nil,
                        width = "half",
                        func = function()
                            doodle[propertyToAdd] = inheritedProperties[propertyToAdd]
                            self:updateConfig()
                            reloadPanel()
                        end,
                    },
                    
                    --Add buttons to remove the doodle, move it up and move it down.
                    h2 = {
                        type = 'header',
                        name = 'Actions',
                        order = 200
                    },
                    deleteDoodle = {
                        type = 'execute',
                        name = 'Delete',
                        desc = 'Delete this doodle.  Be careful!',
                        width = "half",
                        func = function()
                            yesnoBox('Are you sure you want to delete this doodle?', function()
                                table.remove(doodleSet[unitName], i)
                                self:updateConfig()
                                reloadPanel()
                            end)
                        end,
                        order = 201
                    },
                    moveUp = {
                        type = 'execute',
                        name = 'Move up',
                        width = "normal",
                        desc = 'Moves this doodle up in the list.',
                        disabled = i == 1,
                        func = function()
                            --Remove from current position
                            table.remove(doodleSet[unitName],i)
                            --Insert in earlier position
                            table.insert(doodleSet[unitName], i - 1, doodle)
                            self:updateConfig()
                            reloadPanel()
                        end,
                        order = 202
                    },
                    moveDown = {
                        type = 'execute',
                        name = 'Move down',
                        width = "normal",
                        desc = 'Moves this doodle down in the list.',
                        disabled = i == #doodles,
                        func = function()
                            --Remove from current position
                            table.remove(doodleSet[unitName],i)
                            --Insert in later position
                            table.insert(doodleSet[unitName], i + 1, doodle)
                
                            self:updateConfig()
                            reloadPanel()
                        end,
                        order = 203
                    },
                },
                order = 10+i,
            }
        
            --Inject options table handlers for each property defined in this doodle
        
            local setProperties = {}
            for propertyName, value in pairs(doodle) do
                options.args[unitName].args["doodle"..i].args[propertyName] = self:getPropertyHandler(doodle, propertyName, updateConfig, reloadPanel)
                setProperties[propertyName] = propertyName
                if propertyName == 'doodleType' then
                    options.args[unitName].args["doodle"..i].args[propertyName].order = 1
                end
            end
        
            local propertyToRemove = keys(setProperties)[1]
        
            options.args[unitName].args["doodle"..i].args.propertyToRemove = {
                type = 'select',
                name = 'Property to remove',
                order = 105,
                desc = 'Select a property to remove.  This doodle will fallback on inherited defaults for this property.',
                values = setProperties,
                get = function() return propertyToRemove end,
                set = function(info, value) propertyToRemove = value end,
                disabled = propertyToRemove==nil
            }
        
            options.args[unitName].args["doodle"..i].args.removeProperty = {
                type = 'execute',
                name = 'Remove',
                width = 'half',
                desc = 'Remove the selected property.',
                order = 106,
                func = function()
                    doodle[propertyToRemove] = nil
                    self:updateConfig()
                    reloadPanel()
                end,
            }
        
        end
    
    end
    
    return options

end

function unitDoodlesConfig:editDoodleDefaults()

    if self.doodleDefaultsContainer == nil then 
        self.doodleDefaultsContainer = AceGUI:Create("Frame")
        self.doodleDefaultsContainer:SetTitle("Doodle defaults")
    end
    
    local function panelReloadCall()
        return function()
            local panel = self:createDoodleDefaultsPanel(panelReloadCall())
            AceConfig:RegisterOptionsTable("unitDoodles.doodleDefaults", panel)
            AceConfigDialog:Open("unitDoodles.doodleDefaults", self.doodleDefaultsContainer)
        end
    end
    
    panelReloadCall()()

end

function unitDoodlesConfig:editDoodleSet(setName)

    if self.editDoodleContainer == nil then 
        self.editDoodleContainer = AceGUI:Create("Frame")
    end
    
    self.editDoodleContainer:SetTitle(setName)
    
    local function panelReloadCall()
        return function()
            local panel = self:createDoodlePanel(setName, panelReloadCall())
            AceConfig:RegisterOptionsTable("unitDoodles.editDoodles", panel)
            AceConfigDialog:Open("unitDoodles.editDoodles", self.editDoodleContainer)
        end
    end
    
    panelReloadCall()()
    
end

function unitDoodlesConfig:shareDoodleSet(setName)
    
    if self.shareContainer == nil then
        self.shareContainer = AceGUI:Create("Frame")
    end
    
    local serializedDoodles = self:Serialize(setName, self.config.doodleSets[setName])
    
    self.shareContainer:SetTitle("Share "..setName)
    local characterName = ''
    local panel = {
        type = 'group',
        name = 'Share '..setName,
        args = {
            h1 = {
                type = 'header',
                name = 'Send Doodles',
                order = 10,
            },
            d1 = {
                type = 'description',
                name = 'You can send this doodle set to another player by entering their name below.  They will then be prompted to accept the offer.',
                order = 11,
            },
            characterName = {
                type = 'input',
                name = 'Character name:',
                desc = 'Enter the name of a player to send this doodle set to.  They must have unitDoodles.Config active to accept your doodle offer.',
                get = function() return characterName end,
                set = function(info, value) characterName = value end,
                order = 12,
            },
            sendDoodles = {
                type = 'execute',
                name = 'Send',
                func = function()
                    self:SendCommMessage("unitDoodles.sendDoodles", serializedDoodles, "WHISPER", characterName)
                end,
                order = 13,
            },
        
            h2 = {
                type = 'header',
                name = 'Broadcast Doodles',
                order = 20,
            },
            d2 = {
                type = 'description',
                name = 'You can send this doodle set to your party, raid or guild.  Recipients will then be prompted to accept the offer.',
                order = 21,
            },
            sendParty = {
                type = 'execute',
                name = 'Party',
                func = function()
                    self:SendCommMessage("unitDoodles.sendDoodles", serializedDoodles, "PARTY")
                end,
                order = 22,
            },
            sendRaid = {
                type = 'execute',
                name = 'Raid',
                func = function()
                    self:SendCommMessage("unitDoodles.sendDoodles", serializedDoodles, "RAID")
                end,
                order = 23,
            },
            sendGuild = {
                type = 'execute',
                name = 'Guild',
                func = function()
                    self:SendCommMessage("unitDoodles.sendDoodles", serializedDoodles, "GUILD")
                end,
                order = 24,
            },
        
            h3 = {
                type = 'header',
                name = 'Copy to clipboard',
                order = 30,
            },
            d3 = {
                type = 'description',
                name = 'To copy the text in this box to the clipboard:  (1) put your cursor in front of the first character by left clicking, (2) hold down shift + down arrow to select all of the text, (3) hit ctrl+c to copy to the clipboard.\n\nYou can submit doodle sets for inclusion in the standard unitDoodles distribution by submitting a comment on Curse.com, opening a feature ticket at http://code.google.com/p/browniehelper/, or emailing sonora.kirintor@gmail.com.',
                order = 31,
            },
            serialText = {
                type = 'input',
                name = 'Doodle set text:',
                multiline = true,
                width = 'full',
                order = 32,
                get = function() return DataDumper(self.config.doodleSets[setName]) end,
                set = function() end,
            }
        }
    }
    
    AceConfig:RegisterOptionsTable("unitDoodles.shareDoodles", panel)
    AceConfigDialog:Open("unitDoodles.shareDoodles", self.shareContainer)
    
end


function unitDoodlesConfig:sendDoodlesReciever(prefix, message, distribution, sender)

    local playerName = UnitName('player')
    if sender~=playerName then

        local success, setName, doodleSet = self:Deserialize(message)
        
        yesnoBox("You have been sent a doodle set named '"..setName.."' from "..sender..".  Would you like to add this doodle set to your local unitDoodles configuration?",
            function()
                local function addSet()
                    self.config.doodleSets[setName] = doodleSet
                    self:updateConfig()
                    self:panelLoader("unitDoodles.doodleSets", self.createDoodleSetsPanel)()
                end

                if self.config.doodleSets[text] == nil then addSet()
                else
                    yesnoBox("You already have a doodle set named '"..text.."'.  Adding a new set with this name will delete the old set.  Are you sure you want to do this?", addSet)
                end
            end
        )
    
    end
    
end
